from fastapi import Request
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.service.dict_service import DictDataService
from module_plant.dao.plot_dao import PlotDao
from module_plant.entity.vo.plot_vo import DeletePlotModel, PlotModel, PlotPageQueryModel
from utils.common_util import CamelCaseUtil
from utils.excel_util import ExcelUtil


class PlotService:
    """
    种植地块模块服务层
    """

    @classmethod
    async def get_plot_list_services(
        cls, query_db: AsyncSession, query_object: PlotPageQueryModel, is_page: bool = False
    ):
        """
        获取种植地块列表信息service

        :param query_db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 种植地块列表信息对象
        """
        plot_list_result = await PlotDao.get_plot_list(query_db, query_object, is_page)

        return plot_list_result


    @classmethod
    async def add_plot_services(cls, query_db: AsyncSession, page_object: PlotModel):
        """
        新增种植地块信息service

        :param query_db: orm对象
        :param page_object: 新增种植地块对象
        :return: 新增种植地块校验结果
        """
        try:
            await PlotDao.add_plot_dao(query_db, page_object)
            await query_db.commit()
            return CrudResponseModel(is_success=True, message='新增成功')
        except Exception as e:
            await query_db.rollback()
            raise e

    @classmethod
    async def edit_plot_services(cls, query_db: AsyncSession, page_object: PlotModel):
        """
        编辑种植地块信息service

        :param query_db: orm对象
        :param page_object: 编辑种植地块对象
        :return: 编辑种植地块校验结果
        """
        edit_plot = page_object.model_dump(exclude_unset=True, exclude={'create_time', 'create_by', })
        plot_info = await cls.plot_detail_services(query_db, page_object.plot_id)
        if plot_info.plot_id:
            try:
                await PlotDao.edit_plot_dao(query_db, edit_plot)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='更新成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='种植地块不存在')

    @classmethod
    async def delete_plot_services(cls, query_db: AsyncSession, page_object: DeletePlotModel):
        """
        删除种植地块信息service

        :param query_db: orm对象
        :param page_object: 删除种植地块对象
        :return: 删除种植地块校验结果
        """
        if page_object.plot_ids:
            plot_id_list = page_object.plot_ids.split(',')
            try:
                for plot_id in plot_id_list:
                    await PlotDao.delete_plot_dao(query_db, PlotModel(plotId=plot_id))
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='删除成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='传入地块Id为空')

    @classmethod
    async def plot_detail_services(cls, query_db: AsyncSession, plot_id: int):
        """
        获取种植地块详细信息service

        :param query_db: orm对象
        :param plot_id: 地块Id
        :return: 地块Id对应的信息
        """
        plot = await PlotDao.get_plot_detail_by_id(query_db, plot_id=plot_id)
        if plot:
            result = PlotModel(**CamelCaseUtil.transform_result(plot))
        else:
            result = PlotModel(**dict())

        return result

    @staticmethod
    async def export_plot_list_services(request: Request, plot_list: List):
        """
        导出种植地块信息service

        :param plot_list: 种植地块信息列表
        :return: 种植地块信息对应excel的二进制数据
        """
        # 创建一个映射字典，将英文键映射到中文键
        mapping_dict = {
            'plotId': '地块Id',
            'plotName': '地块名称',
            'plotNo': '地块编号',
            'plotCenterCoordinates': '地块坐标',
            'plotBoundary': '地块边界',
            'cropVarietyId': '种植品种Id',
            'cropVariety': '种植品种',
            'year': '数据年份',
            'productAreaId': '产区Id',
            'productArea': '产区',
            'planterId': '种植主体Id',
            'planterName': '种植主体',
            'address': '地址',
            'plotAreaSize': '地块面积',
            'memo': '备注',
            'createTime': '创建时间',
            'createBy': '创建人',
            'updateTime': '更新时间',
            'updateBy': '更新人',
        }
        product_area_list = await DictDataService.query_dict_data_list_from_cache_services(
            request.app.state.redis, dict_type='product_area'
        )
        product_area_option = [dict(label=item.get('dictLabel'), value=item.get('dictValue')) for item in product_area_list]
        product_area_option_dict = {item.get('value'): item for item in product_area_option}
        for item in plot_list:
            if str(item.get('productAreaId')) in product_area_option_dict.keys():
                item['productAreaId'] = product_area_option_dict.get(str(item.get('productAreaId'))).get('label')
        binary_data = ExcelUtil.export_list2excel(plot_list, mapping_dict)

        return binary_data
